#!/usr/bin/env python

# Copyright 2017, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

try:
    import httplib
except ImportError:
    import http.client as httplib
import ssl
try:
    import urlparse
except ImportError:
    import urllib.parse as urlparse
import sys


__DOC__ = """
USAGE:
  This script will take arguments passed into it to discover the url
  of a given container image using the distro, release, architecture,
  and variant as the parameters.

EXAMPLE:
# python lxc-image-fetch-url ubuntu xenial amd64 default
"""

LXC_CACHE_SERVER = '{{ lxc_image_cache_server_mirrors[0].strip() }}'
LXC_INDEX = '{0}/meta/1.0/index-system'.format(LXC_CACHE_SERVER)


def get_image_url(url, depth=0):
    if depth > 10:
        raise SystemExit('Too many redirects')

    url_path = urlparse.urlparse(url, allow_fragments=True)
    if url_path.scheme == 'https':
        conn = httplib.HTTPSConnection(
            host=url_path.netloc,
            context=ssl._create_unverified_context()
        )
    else:
        conn = httplib.HTTPConnection(host=url_path.netloc)

    try:
        conn.request('GET', url_path.path)
    except httplib.BadStatusLine:
        raise SystemExit('Connection Failure')
    else:
        resp = conn.getresponse()
        headers = dict(resp.getheaders())
        check_redirect = headers.get('location', None)
        if not check_redirect:
            check_redirect = headers.get('Location', None)

        if check_redirect:
            depth += 1
            return get_image_url(
                url=check_redirect,
                depth=depth
            )
        else:
            return (
                str(url),
                resp.read().decode('UTF-8').splitlines()
            )
    finally:
        conn.close()


def main():
    try:
        distro = sys.argv[1]
        release = sys.argv[2]
        arch = sys.argv[3]
        variant = sys.argv[4]
    except IndexError:
        print('Missing argument, Please see the documentation.')
        raise SystemExit(__DOC__)

    _, meta = get_image_url(url=LXC_INDEX, depth=0)
    image_hint = '{0};{1};{2};{3}'.format(
        distro,
        release,
        arch,
        variant
    )

    images = sorted([i for i in meta if i.strip().startswith(image_hint)])
    if not images:
        print(__DOC__ + '\nAvailable options:')
        for line in meta:
            print(';'.join(line.split(';')[:-2]))

        raise SystemExit(
            'No Image found with image hint "{0}"'.format(image_hint)
        )

    container_url = urlparse.urljoin(
        urlparse.urljoin(
            LXC_CACHE_SERVER,
            images[0].split(';')[-1]
        ),
        'rootfs.tar.xz'
    )
    print(container_url)

if __name__ == '__main__':
    main()
